home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / examples / programs / graph_disp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-08  |  24.2 KB  |  708 lines

  1. #ifndef lint
  2. static char SccsId[]= "@(#)graph_disp.c    1.18 3/13/95 13:12:15";
  3. #endif
  4. /*
  5. |    file name - graph_disp.c
  6. |===================================================================
  7. |
  8. |    This program demonstrates how to utilize drawports for
  9. |    graphs to be displayed and manipulated.  Each graph may
  10. |    be updated and will be maintained within their own drawport.
  11. |
  12. |    The program also allows the user to manipulate the graphs
  13. |    in the following manners: Zoom in, Zoom Out, Increase
  14. |    the Range or Decrease the Range of the variables assigned
  15. |    to the graphs and Reset the graphs to their original state.
  16. |
  17. |    Except for the update operation, each operation is performed
  18. |    only on the currently selected graph which is identified by
  19. |    an arrow.
  20. |
  21. |    The example shows how the history of the graph is being
  22. |    maintained by the graph and displayed appropriately when
  23. |    redrawing occurs or changes to the ranges of the variable
  24. |    descriptors are made.
  25. |
  26. |===================================================================
  27. */
  28. #include <windows.h>
  29. /*
  30.  *  DV-Tools header files
  31.  */
  32. #include "std.h"                /* <stdio.h> etc., scalar & macro definitions */
  33. #include "dvstd.h"              /* public types & constants */
  34. #include "dvtools.h"            /* constants used by T routines */
  35. #include "dvGR.h"               /* constants used by window mgt & GR routines */
  36. #include "VOstd.h"              /* constants used by VO & VOob routines */
  37. #include "Tfundecl.h"           /* T routines (screens, drawports & views) */
  38. #include "VOfundecl.h"          /* VO routines (objects) */
  39. #include "VGfundecl.h"          /* VG routines (get info from dgp & vdp) */
  40. #include "VPfundecl.h"          /* VP routines (put info for dgp & vdp) */
  41. #include "VUerfundecl.h"        /* VUer routines (event handling routines) */
  42.  
  43. /* Constants */
  44. #define  DVPATH            (char *)NULL
  45. #define  DISPFORMS_STB     (char *)NULL
  46. #define  DVDEVICE          (char *)NULL
  47. #define  DVCOLORTABLE      (char *)NULL
  48. #define  VIEW_NAME       "graph_disp.v"
  49. #define  SCREEN_VIEWPORT   (RECTANGLE *)NULL
  50. #define  ENTIRE_DRAWPORT   (RECTANGLE *)NULL
  51. #define  MAX_GRAPHS       3
  52.  
  53. /* Define the selection values from the control menu */
  54. #define UPDATE        1
  55. #define ZOOM_IN        2
  56. #define ZOOM_OUT    3
  57. #define RESET        4
  58. #define INCR_RANGE    5
  59. #define DECR_RANGE    6
  60. #define QUIT        7
  61. #define MENU_CLIENT    1
  62.  
  63. /* Define global variables */
  64. DRAWPORT main_drawport;         /* how & where to display picture, picture frame */
  65. OBJECT control_menu,            /* menu input object */
  66.        msg_object;              /* text object used for prompts & messages */
  67. int current_graph;              /* index representing selected graph */
  68. int Quit = NO;                  /* flag to quit program */
  69. float control_var,              /* variable buffer for menu input object */
  70.       arrow_var;                /* variable buffer for dynamic polygon */
  71. double CurrentScale[MAX_GRAPHS] = {1.0, 1.0, 1.0};
  72. double ZoomInScale = 2.0, ZoomOutScale = 0.5;
  73.  
  74. /* Define list of graph areas and view names with graphs */
  75. char *Graph_Areas[MAX_GRAPHS] = {"graph1.v", "graph2.v", "graph3.v"};
  76.  
  77. /* Whole world rectangle, (-16384, -16384) to (16383, 16383)*/
  78. RECTANGLE whole_world = {XMIN, YMIN, XMAX, YMAX};
  79.  
  80. /* Define the values to designate where along the path the arrow should be. */
  81. float graph_arrow_val[MAX_GRAPHS] = {0.0, 0.5, 1.0};
  82.  
  83. /* Define structure containing graph information */
  84. typedef struct
  85. {
  86.   DRAWPORT drawport;                /* how & where to display graph view */
  87.   VIEW view;                        /* picture of graph view */
  88.   OBJECT graph;                     /* graph object */
  89.   DATAGROUP dgp_ptr;                /* pointer to data group structure */
  90.   VARDESC vdplist[MAX_GRAPHS + 1];  /* list of vdps */
  91.   double low_range[MAX_GRAPHS + 1]; /* original low range of vdp */
  92.   double high_range[MAX_GRAPHS + 1];/* original high range of vdp */
  93. } GRAPH_INFO;
  94.  
  95. GRAPH_INFO GraphInfo[MAX_GRAPHS];
  96.  
  97. /* Functions defined in graph_disp.c */
  98. void GetObjects V_P_((OBJECT screen, OBJECT drawing));
  99. ADDRESS GetGraph V_P_((OBJECT object, ADDRESS args));
  100. void GetCurrentDrawport V_P_((DRAWPORT drawport));
  101. void ChangeRange V_P_((ADDRESS incrdecr));
  102.  
  103.  
  104. /*
  105.  *   MAIN PROGRAM
  106.  */
  107. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
  108.                      LPSTR lpCmdLine, int nCmdShow )
  109. {
  110.   INT argc = 0;
  111.   CHAR **argv;
  112.   /*
  113.    *  program arguments
  114.    *    argv[1] - display device (default is DVDEVICE)
  115.    */
  116.  
  117.   /* Define & initialize device name and view filename */
  118.   char *device_name = DVDEVICE; /* default device name */
  119.   char *view_name = VIEW_NAME;  /* default view name */
  120.  
  121.   /* Define display variable */
  122.   OBJECT screen;                /* display device, the window */
  123.   VIEW main_view;               /* picture representation of the view file */
  124.  
  125.   /* Control loop variables */
  126.   OBJECT location;              /* the event representation */
  127.   int event_req_status;         /* status of event requests */
  128.  
  129.   /* Other variables */
  130.   DRAWPORT selected_drawport;   /* represents current selected drawport */
  131.   OBJECT drawing;               /* graphical representation of screen */
  132.   int i;                        /* counter */
  133.  
  134.   /*-----------------
  135.    *  Initialization
  136.    *
  137.    *  TInit:    perform the initialization of DV-Tools
  138.    *            TInit reads your configuration file and any
  139.    *            environment variables or logical names set.
  140.    */
  141.   make_argv(&argc,&argv,GetCommandLine());
  142.   TInit( DVPATH, DISPFORMS_STB );
  143.  
  144.   /*
  145.    *  TscOpenSet:  opens a device as a screen object using
  146.    *               specified attributes
  147.    *
  148.    *  Set exposure block to YES to insure the window
  149.    *  is ready for drawing when TdpDraw is called.
  150.    */
  151.   if (argc > 1)
  152.     device_name = argv[1];
  153.   screen = TscOpenSet (NULL, DVCOLORTABLE,
  154.                        V_WINDOW_NAME, "Graph Display",
  155.                        V_WINDOW_WIDTH, 700, V_WINDOW_HEIGHT, 700,
  156.                        V_X_EXPOSURE_BLOCK, YES,
  157.                        V_ACTIVE_CURSOR, V_END_OF_LIST);
  158.   if (!screen)
  159.     {
  160.       printf ("Must specify device on command line or");
  161.       printf (" in DataViews configuration file.\n");
  162.       S_EXIT (EXIT_ERR);
  163.     }
  164.  
  165.   /*
  166.    *  VOscWinEventMask:  sets the screen's window event mask
  167.    */
  168.   VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS |
  169.                             V_MOTIONNOTIFY | V_EXPOSE | V_RESIZE,
  170.                     (ULONG) 0);
  171.  
  172.   /*
  173.    *  TviLoad:   Load a view in from a file,
  174.    *             the view is graph_disp.v
  175.    */
  176.   main_view = TviLoad (view_name);
  177.   if (!main_view)
  178.     {
  179.       printf ("Could not load view from file ");
  180.       printf ("%s.\n", view_name);
  181.       S_EXIT (EXIT_ERR);
  182.     }
  183.  
  184.   /*
  185.    *  TdpCreateStretch: Create a DV-tools window, a drawport
  186.    *                "drawport" is attached to the screen object, "screen"
  187.    *                "view" is the view to be displayed on the screen
  188.    *                "SCREEN_VIEWPORT" specifies the area of the screen
  189.    *                      to use to display the drawport
  190.    *                "whole_world" specifies the portion of the view to be
  191.    *                      displayed, here the whole view
  192.    *                The whole view will be stretched to fit in the drawport
  193.    */
  194.   main_drawport = TdpCreateStretch (screen, main_view,
  195.                                     SCREEN_VIEWPORT, &whole_world);
  196.  
  197.   /*
  198.    *  TviGetDrawing:  Gets the drawing object which TviLoad created
  199.    *              as part of the view structure.
  200.    *  GetObjects:     Extracts the graph objects from the main view
  201.    *              A drawport will be created in which to display
  202.    *              each graph object.
  203.    *  Then initialize some internal identifiers.
  204.    */
  205.   drawing = TviGetDrawing (main_view);
  206.   GetObjects (screen, drawing);
  207.   current_graph = 0;
  208.   arrow_var = graph_arrow_val[0];
  209.  
  210.   /*
  211.    *  TscErase:    erase the entire screen in the default background color
  212.    *  TscDraw:     Draw the contents of the drawport
  213.    *  TviOpenData: Open all data source lists for this view and views
  214.    *           referenced by enabled subdrawings contained in view.
  215.    *  TviReadData: Reads data from the data sources of a view
  216.    *
  217.    *  Erase the screen and draw the contents of the main drawport.
  218.    *  Then open and read the data source lists for the views containing
  219.    *  the graphs and draw their drawports.
  220.    */
  221.   TscErase (screen);
  222.   TdpDraw (main_drawport);
  223.   for (i = (MAX_GRAPHS - 1); i >= 0; i--)
  224.     {
  225.       TviOpenData (GraphInfo[i].view);
  226.       TviReadData (GraphInfo[i].view);
  227.       TdpDraw (GraphInfo[i].drawport);
  228.     }
  229.  
  230.   FOREVER
  231.   {
  232.     /*
  233.      *  VOloWinEventPoll:  Poll for the next window event.
  234.      *                     The polling mode used is V_WAIT.
  235.      *                     Therefore, VOloWinEventPoll does not
  236.      *                     return until a masked event is
  237.      *                     generated.  V_WAIT always produces
  238.      *                     a valid location object.
  239.      * VUerHandleLocEvent: Service the event. This routine will check
  240.      *                     if the event is used by any input objects
  241.      *                     that may be in the view.
  242.      */
  243.     location = VOloWinEventPoll (V_WAIT);
  244.     event_req_status = VUerHandleLocEvent (location);
  245.     if (event_req_status == INPUT_UNUSED)
  246.       {
  247.  
  248.         /*
  249.          *  VOloType:  returns the type of event.  These types
  250.          *             match event types specified in VOscWinEventMask.
  251.          */
  252.         switch (VOloType (location))
  253.           {
  254.  
  255.           case V_RESIZE:
  256.             /*
  257.              *  The window size has been changed.
  258.              *  TscReset:  Resets all screen drawports after window
  259.              *        resizing.
  260.              */
  261.             TscReset (screen);
  262.             break;
  263.  
  264.           case V_EXPOSE:
  265.             /*
  266.              *  VOloRegion:  Returns a rectangle representing the
  267.              *               exposed region on the screen.
  268.              *  TscRedraw:   After erasing, redraws all the drawports
  269.              *               in the screen.
  270.              *  A portion of the window has been exposed and needs
  271.              *  to be redrawn.
  272.              */
  273.             TscRedraw (screen, VOloRegion (location));
  274.             break;
  275.  
  276.           case V_KEYPRESS:
  277.             /*
  278.              *  Check key selected.
  279.              *  VOloKeySym:  Returns the key symbol value of the
  280.              *               location object
  281.              *
  282.              *  If the key symbol represents the characters 'q'
  283.              *  or 'Q' then quit the program.
  284.              */
  285.             switch (VOloKeySym (location))
  286.               {
  287.               case 'q':
  288.               case 'Q':
  289.                 Quit = YES;
  290.                 break;
  291.               }
  292.             break;
  293.  
  294.           case V_BUTTONPRESS:
  295.             /*
  296.              *  Check button selected.
  297.              *  VOloButton:  Returns the button that was pressed
  298.              *  TloGetSelectedDrawport:  Gets selected drawport
  299.              *  TdpDrawNext: Updates all dynamic objects (arrow)
  300.              *
  301.              *  The left mouse button acts as the selection button.
  302.              *  Check to see if the user selected a graph drawport.
  303.              *  If so, then set the current graph drawport and
  304.              *  draw this graph_drawport on the top. The right
  305.              *  mouse button exits the program.
  306.              */
  307.             switch (VOloButton (location))
  308.               {
  309.               case 1:
  310.                 selected_drawport = TloGetSelectedDrawport (location);
  311.                 GetCurrentDrawport (selected_drawport);
  312.                 TdpDrawNext (main_drawport);
  313.                 break;
  314.  
  315.               case 3:
  316.                 Quit = YES;
  317.                 break;
  318.  
  319.               default:
  320.                 break;
  321.               }
  322.             break;
  323.           }
  324.       }
  325.     if (Quit == YES)
  326.       break;
  327.   }
  328.  
  329.   /*--------------------
  330.    *   Termination
  331.    *
  332.    *   TdpDestroy:            Destroy the drawport,
  333.    *   TviCloseData:          Close the data sources of the view
  334.    *   TviDestroy:            Destroy the view, freeing the allocated memory
  335.    *   TscClose:              Closes the screen object
  336.    *   TTerminate:            Perform the clean-up for DV-Tools
  337.    */
  338.   TscErase (screen);
  339.   for (i = 0; i < MAX_GRAPHS; i++)
  340.     {
  341.       TdpDestroy (GraphInfo[i].drawport);
  342.       TviCloseData (GraphInfo[i].view);
  343.       TviDestroy (GraphInfo[i].view);
  344.     }
  345.   TdpDestroy (main_drawport);
  346.   TviDestroy (main_view);
  347.   TscClose (screen);
  348.   TTerminate ();
  349.   return (EXIT_OK);
  350. }
  351.  
  352.  
  353. /*--------------
  354.  *   HandleInput  -- Service result routine called when a selection
  355.  *   is made from the main menu. Check the selection made and perform
  356.  *   the appropriate action.
  357.  */
  358. /*ARGSUSED*/
  359. LOCAL int 
  360. HandleInput (client, er, label, loc, args)
  361.      OBJECT client;
  362.      EVENT_REQUEST er;
  363.      int label;
  364.      OBJECT loc;
  365.      ADDRESS args;
  366. {
  367.   char incrdecrflag;
  368.   double scale;
  369.   int i;
  370.   OBJECT dp_xform;
  371.  
  372.   /*
  373.    *  Clear message string
  374.    */
  375.   TdpEraseObject (main_drawport, msg_object);
  376.   VOtxSetString (msg_object, "");
  377.   TdpDrawObject (main_drawport, msg_object);
  378.  
  379.   /*
  380.    *  Check the menu selection and perform the appropriate action
  381.    *  based on the menu selection.
  382.    */
  383.   switch ((int) (control_var))
  384.     {
  385.       /*
  386.        *  Read the next iteration of data from each view and
  387.        *  update all dynamic objects with new data.
  388.        */
  389.     case UPDATE:
  390.       for (i = 0; i < MAX_GRAPHS; i++)
  391.         {
  392.           TviReadData (GraphInfo[i].view);
  393.           TdpDrawNext (GraphInfo[i].drawport);
  394.         }
  395.       break;
  396.  
  397.       /*
  398.        *  TdpGetScale:  Gets scale factor of a drawport
  399.        *  TdpZoom:      Scales the drawing in the drawport
  400.        *  TdpRedraw:    Redraws a portion of the drawport
  401.        *
  402.        *  Check the current scale of the drawport. Then scale the
  403.        *  drawport by the scale factor defined by ZoomInScale.
  404.        */
  405.     case ZOOM_IN:
  406.       if (TdpGetScale (GraphInfo[current_graph].drawport) < 1.0)
  407.         {
  408.           TdpZoom (GraphInfo[current_graph].drawport, ZoomInScale);
  409.           TdpRedraw (GraphInfo[current_graph].drawport,
  410.                             ENTIRE_DRAWPORT, YES);
  411.           CurrentScale[current_graph] *= ZoomInScale;
  412.         }
  413.       break;
  414.  
  415.       /*
  416.        *  TdpGetScale:  Gets scale factor of a drawport
  417.        *  TdpZoom:      Scales the drawing in the drawport
  418.        *  TdpRedraw:    Redraws a portion of the drawport
  419.        *
  420.        *  Check the current scale of the drawport. Then scale the
  421.        *  drawport by the scale factor defined by ZoomOutScale.
  422.        */
  423.     case ZOOM_OUT:
  424.       if (TdpGetScale (GraphInfo[current_graph].drawport) > (1 / 14171.0))
  425.         {
  426.           TdpZoom (GraphInfo[current_graph].drawport, ZoomOutScale);
  427.           dp_xform = TdpGetXform (GraphInfo[current_graph].drawport,
  428.                                   DR_TO_SCREEN);
  429.           if (VOdgIsDrawable (GraphInfo[current_graph].graph, dp_xform) == YES)
  430.             {
  431.               TdpRedraw (GraphInfo[current_graph].drawport,
  432.                                 ENTIRE_DRAWPORT, YES);
  433.               CurrentScale[current_graph] *= ZoomOutScale;
  434.             }
  435.           else
  436.             {
  437.               VOtxSetString (msg_object,
  438.                  "Graph cannot be displayed properly; Drawport is not scaled");
  439.               TdpDrawObject (main_drawport, msg_object);
  440.               TdpZoom (GraphInfo[current_graph].drawport, ZoomInScale);
  441.             }
  442.         }
  443.       break;
  444.  
  445.       /*
  446.        *  Reset the graph drawports to the beginning and return the
  447.        *  drawports to their original scale. Then redraw them.
  448.        */
  449.     case RESET:
  450.       for (i = 1; i <= 3; i++)
  451.         VPvd_drange (GraphInfo[current_graph].vdplist[i],
  452.                      GraphInfo[current_graph].low_range[i],
  453.                      GraphInfo[current_graph].high_range[i]);
  454.       VPdgdfreset (GraphInfo[current_graph].dgp_ptr);
  455.  
  456.       scale = 1.0 / CurrentScale[current_graph];
  457.       TdpZoom (GraphInfo[current_graph].drawport, scale);
  458.       TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
  459.       CurrentScale[current_graph] *= scale;
  460.       break;
  461.  
  462.       /*
  463.        *  Increase the ranges for all variable descriptors associated
  464.        *  with the current graph.  Then redraw the drawport displaying
  465.        *  this graph.
  466.        */
  467.     case INCR_RANGE:
  468.       incrdecrflag = 'i';
  469.       ChangeRange ((ADDRESS) & incrdecrflag);
  470.       TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
  471.       break;
  472.  
  473.       /*
  474.        *  Decrease the ranges for all variable descriptors associated
  475.        *  with the current graph.  Then redraw the drawport displaying
  476.        *  this graph.
  477.        */
  478.     case DECR_RANGE:
  479.       incrdecrflag = 'd';
  480.       ChangeRange ((ADDRESS) & incrdecrflag);
  481.       TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
  482.       break;
  483.  
  484.       /*
  485.        *  Quit the program
  486.        */
  487.     case QUIT:
  488.       Quit = YES;
  489.       break;
  490.     }
  491.  
  492.   return (int) INPUT_USED;
  493. }
  494.  
  495. /*-------------
  496.  *   GetObjects -- Obtain rectangle objects from the main view
  497.  *           which define areas to display graphs. Create
  498.  *           drawports for each graph to be displayed.
  499.  */
  500. void 
  501. GetObjects (screen, drawing)
  502.      OBJECT screen;
  503.      OBJECT drawing;
  504. {
  505.   OBJECT graph_areas, graph_drawing;
  506.   OBJECT dyn_control_object, vd_object, arrow;
  507.   RECTANGLE vvp_screen, wvp_rect, svp_offset;
  508.   VARDESC vdp;
  509.   ADDRESS *vdplist;
  510.   int numvars, i;
  511.  
  512.   /*  TdrGetNamedObject:  Gets a named object from a drawing.
  513.    *  VOinGetVarList:     Gets a variable descriptor list of
  514.    *               the input object.
  515.    *  TvdPutBuffer:       Set a new variable descriptor buffer
  516.    *
  517.    *  Obtain the control menu from the main view. Then, rebind
  518.    *  it's vdp to a program variable.
  519.    */
  520.   control_menu = TdrGetNamedObject (drawing, "control_menu");
  521.   VOinGetVarList (control_menu, &vdplist, &numvars);
  522.   TvdPutBuffer (vdplist[0], (ADDRESS) & control_var);
  523.  
  524.   /*
  525.    *  VUerServiceResultPost:  Post a service result request
  526.    *                          with the event handler.
  527.    *
  528.    *  Post a service result request which monitors the
  529.    *  menu. The request specifies the type of the service
  530.    *  result flag to be generated as an INPUT_DONE. INPUT_DONE
  531.    *  indicates an input sequence has been completed
  532.    *  (a menu selection was made).
  533.    */
  534.   VUerServiceResultPost ((OBJECT) MENU_CLIENT, (VUERFCNFUNPTR)HandleInput, (ADDRESS)NULL, 0,
  535.                          control_menu, (int)INPUT_DONE, (int)0);
  536.  
  537.   /*  Load in the views containing the graphs to be displayed in the
  538.    *  main drawport. Create a drawport for each graph to be displayed
  539.    *  using the rectangles from the main view as the dimensions for
  540.    *  these drawports.
  541.    */
  542.   for (i = 0; i < MAX_GRAPHS; i++)
  543.     {
  544.       graph_areas = TdrGetNamedObject (drawing, Graph_Areas[i]);
  545.       VOobBox (graph_areas, &wvp_rect, &svp_offset);
  546.       vvp_screen.ll.x = wvp_rect.ll.x + XMAX;
  547.       vvp_screen.ll.y = wvp_rect.ll.y + YMAX;
  548.       vvp_screen.ur.x = wvp_rect.ur.x + XMAX;
  549.       vvp_screen.ur.y = wvp_rect.ur.y + YMAX;
  550.  
  551.       GraphInfo[i].view = TviLoad (Graph_Areas[i]);
  552.       GraphInfo[i].drawport = TdpCreateStretch (screen, GraphInfo[i].view,
  553.                                            &vvp_screen, &whole_world);
  554.  
  555.       /*
  556.        *  TobForEachSubobject:  Traverses all subobjects in an object.
  557.        *  VOdrObDelete:          Deletes an object from a drawing
  558.        *
  559.        *  For each graph object in the graph drawing, obtain the
  560.        *  information such as dgp and range of vdp. Delete the
  561.        *  graph area rectangle from the main drawing.
  562.        */
  563.       graph_drawing = TviGetDrawing (GraphInfo[i].view);
  564.       TobForEachSubobject (graph_drawing, (TOBFOREACHSUBOBJFUNPTR)GetGraph, (ADDRESS) & i);
  565.       VOdrObDelete (drawing, graph_areas);
  566.     }
  567.  
  568.   /*
  569.    *  VOobDyGet:      Returns the dynamic control object attached to
  570.    *               the object.
  571.    *  VOdyGetDataObj: Returns the first data control object attached
  572.    *               to the dynamic object.
  573.    *  VOvdGetVdp:     Gets the pointer to the variable descriptor
  574.    *
  575.    *  Obtain the variable descriptor for the arrow which is
  576.    *  to be used to indicate which graph is the currently selected
  577.    *  graph.
  578.    */
  579.   arrow = TdrGetNamedObject (drawing, "arrow");
  580.   dyn_control_object = VOobDyGet (arrow);
  581.   vd_object = VOdyGetDataObj (dyn_control_object, V_DYN_PATH_MOVE, 1);
  582.   vdp = VOvdGetVdp (vd_object);
  583.   TvdPutBuffer (vdp, (ADDRESS) & arrow_var);
  584.  
  585.   /*
  586.    *  VOtxSetString:  Redefines string associated with the text object.
  587.    *
  588.    *  Obtain the message text object and initialize the string.
  589.    */
  590.   msg_object = TdrGetNamedObject (drawing, "msg_object");
  591.   VOtxSetString (msg_object, "");
  592. }
  593.  
  594.  
  595. /*----------
  596.  *  GetGraph -- Obtain the graph object, it's data group pointer and
  597.  *        the variable descriptors associated with this graph.
  598.  *        Also obtain the range of the vdps for the graph.
  599.  */
  600. ADDRESS 
  601. GetGraph (object, args)
  602.      OBJECT object;
  603.      ADDRESS args;
  604. {
  605.   int i, num_of_vdps;
  606.   int *graph_index = (int *)args;
  607.  
  608.   /*
  609.    *  VOobType:   Returns the type flag of an object
  610.    *  VOdgGetDgp: Returns pointer to the data group structure
  611.    *  VGdgvd:     Gets the address or number of vdps from a data group
  612.    */
  613.   if (VOobType (object) == OT_DG)
  614.     {
  615.       GraphInfo[*graph_index].graph = object;
  616.       GraphInfo[*graph_index].dgp_ptr = VOdgGetDgp (object);
  617.       num_of_vdps = (int) VGdgvd (GraphInfo[*graph_index].dgp_ptr, 0);
  618.       for (i = 1; i <= num_of_vdps; i++)
  619.         {
  620.           GraphInfo[*graph_index].vdplist[i] = (VARDESC) VGdgvd (
  621.                                   GraphInfo[*graph_index].dgp_ptr, i);
  622.           VGvd_drange (GraphInfo[*graph_index].vdplist[i],
  623.                        &GraphInfo[*graph_index].low_range[i],
  624.                        &GraphInfo[*graph_index].high_range[i]);
  625.         }
  626.     }
  627.  
  628.   return V_CONTINUE_TRAVERSAL;
  629. }
  630.  
  631.  
  632. /*--------------------
  633.  *  GetCurrentDrawport -- Determine which drawport is the currently
  634.  *  selected drawport.  The actions selected from the main menu are
  635.  *  performed on the currently selected drawport.  The currently
  636.  *  selected drawport is pointed to by an arrow object which moves
  637.  *  along a path based on which drawport is currently selected.
  638.  */
  639. void 
  640. GetCurrentDrawport (drawport)
  641.      DRAWPORT drawport;
  642. {
  643.   int i;
  644.  
  645.   /*
  646.    *  TdpFront:  Moves a drawport to the front
  647.    *  TdpRedraw: Redraws a portion of the drawport
  648.    */
  649.   for (i = 0; i < MAX_GRAPHS; i++)
  650.     {
  651.       if (drawport == GraphInfo[i].drawport)
  652.         {
  653.           current_graph = i;
  654.           arrow_var = graph_arrow_val[i];
  655.           TdpFront (GraphInfo[current_graph].drawport);
  656.           TdpRedraw (GraphInfo[current_graph].drawport, ENTIRE_DRAWPORT, YES);
  657.           break;
  658.         }
  659.     }
  660. }
  661.  
  662.  
  663. /*-------------
  664.  *  ChangeRange -- Called when user selected from main menu
  665.  *  to increase or decrease the variable ranges on the graph.
  666.  */
  667. void 
  668. ChangeRange (incrdecr)
  669.      ADDRESS incrdecr;
  670. {
  671.   double low, high, newhigh;
  672.   int i, num_of_vdps;
  673.  
  674.   num_of_vdps = 3;
  675.   for (i = 1; i <= num_of_vdps; i++)
  676.     {
  677.       VGvd_drange (GraphInfo[current_graph].vdplist[i], &low, &high);
  678.       if (*incrdecr == 'd')
  679.         {
  680.           newhigh = (high - low) / 2.0;
  681.           if (low >= newhigh)
  682.             newhigh = high;
  683.  
  684.           /* Set a minimum value which cannot be exceeded. */
  685.           if ((newhigh > 0.0) && (newhigh < 0.00000000001))
  686.             newhigh = 0.00000000001;
  687.           else if ((newhigh < 0) && (newhigh < -0.00000000001))
  688.             newhigh = -0.00000000001;
  689.         }
  690.       else
  691.         {
  692.           newhigh = 2.0 * high;
  693.           if ((newhigh > 0.0) && (newhigh > 10000000000.0))
  694.             newhigh = 10000000000.0;
  695.           else if ((newhigh < 0.0) && (newhigh < -10000000000.0))
  696.             newhigh = -10000000000.0;
  697.         }
  698.  
  699.       VPvd_drange (GraphInfo[current_graph].vdplist[i], low, newhigh);
  700.     }
  701.  
  702.   /*
  703.    *  VPdgdfreset:  Resets the display formatter associated with
  704.    *             a data group.
  705.    */
  706.   VPdgdfreset (GraphInfo[current_graph].dgp_ptr);
  707. }
  708.